@tool
class_name RuleTileData
extends Resource

@export_group("Neighbour")
@export var neightbour_top_left:NeighbourData
@export var neightbour_top:NeighbourData
@export var neightbour_top_right:NeighbourData
@export var neightbour_center_left:NeighbourData
@export var neightbour_center:NeighbourData
@export var neightbour_center_right:NeighbourData
@export var neightbour_bottom_left:NeighbourData
@export var neightbour_bottom:NeighbourData
@export var neightbour_bottom_right:NeighbourData
@export_group("")
@export_group("Addition")
@export var flip_h:bool = false
@export var flip_v:bool = false
@export var rotate_90:bool = false
# 旋转180° == flip_h and flip_v（即执行一次水平翻转以及一次竖直反转）
@export var rotate_180:bool = false
@export var rotate_270:bool = false
@export_group("")
var neighbour_sequence_datas:Array[Array] = []

func init_neighbour_sequence_datas():
	neighbour_sequence_datas.clear()
	neighbour_sequence_datas.append(get_neighbour_sequence())
	if flip_h:
		neighbour_sequence_datas.append(get_flip_h_neighbour_sequence())
	if flip_v:
		neighbour_sequence_datas.append(get_flip_v_neighbour_sequence())
	if rotate_90:
		neighbour_sequence_datas.append(get_rotate_90_neighbour_sequence())
	if rotate_180:
		neighbour_sequence_datas.append(get_rotate_180_neighbour_sequence())
	if rotate_270:
		neighbour_sequence_datas.append(get_rotate_270_neighbour_sequence())
func get_neighbour_sequence() -> Array[NeighbourData]:
	var sequence:Array[NeighbourData] = []
	sequence.append(neightbour_top_left)
	sequence.append(neightbour_top)
	sequence.append(neightbour_top_right)
	sequence.append(neightbour_center_left)
	sequence.append(neightbour_center)
	sequence.append(neightbour_center_right)
	sequence.append(neightbour_bottom_left)
	sequence.append(neightbour_bottom)
	sequence.append(neightbour_bottom_right)
	return sequence
func get_flip_h_neighbour_sequence() -> Array[NeighbourData]:
	var sequence:Array[NeighbourData] = get_neighbour_sequence()
	_flip_h(sequence,3)
	return sequence
func get_flip_v_neighbour_sequence() -> Array[NeighbourData]:
	var sequence:Array[NeighbourData] = get_neighbour_sequence()
	_flip_v(sequence,3)
	return sequence
func get_rotate_90_neighbour_sequence() -> Array[NeighbourData]:
	var sequence:Array[NeighbourData] = []
	sequence.append(neightbour_bottom_left)
	sequence.append(neightbour_center_left)
	sequence.append(neightbour_top_left)
	sequence.append(neightbour_bottom)
	sequence.append(neightbour_center)
	sequence.append(neightbour_top)
	sequence.append(neightbour_bottom_right)
	sequence.append(neightbour_center_right)
	sequence.append(neightbour_top_right)
	return sequence
func get_rotate_180_neighbour_sequence() -> Array[NeighbourData]:
	var sequence:Array[NeighbourData] = get_flip_h_neighbour_sequence()
	sequence = _flip_v(sequence,3)
	return sequence
func get_rotate_270_neighbour_sequence() -> Array[NeighbourData]:
	var sequence:Array[NeighbourData] = get_rotate_90_neighbour_sequence()
	sequence = _flip_h(sequence,3)
	sequence = _flip_v(sequence,3)
	return sequence
func _flip_h(arr:Array,col:int) -> Array:
	var row:int = arr.size()/col
	for r in range(row):
		var idx0 = r * col
		var idx1 = r * col + col - 1
		Util.array_swap(arr,idx0,idx1)
	return arr
func _flip_v(arr:Array,col:int) -> Array:
	var row:int = arr.size()/col
	for c in range(col):
		var idx0 = col
		var idx1 = col * (row - 1) + c
		Util.array_swap(arr,idx0,idx1)
	return arr
func check_is_match_rule(layers:Array[TileMapLayer], coords: Vector2i) -> bool:
	if neighbour_sequence_datas.is_empty():
		init_neighbour_sequence_datas()
	var is_match_rule:bool = false
	var coords_arr:Array[Vector2i] = []
	coords_arr.append(coords + Vector2i(-1,-1))
	coords_arr.append(coords + Vector2i(0,-1))
	coords_arr.append(coords + Vector2i(1,-1))
	coords_arr.append(coords + Vector2i(1,0))
	coords_arr.append(coords)
	coords_arr.append(coords + Vector2i(1,1))
	coords_arr.append(coords + Vector2i(0,1))
	coords_arr.append(coords + Vector2i(-1,1))
	coords_arr.append(coords + Vector2i(-1,0))
	for sequence:Array[NeighbourData] in neighbour_sequence_datas:
		var temp_is_match = true
		for i in range(sequence.size()):
			if sequence[i].flag == NeighbourData.NeighbourFlag.Pass:
				continue
			elif sequence[i].flag == NeighbourData.NeighbourFlag.NotHave:
				temp_is_match = sequence[i].layers.all(func (layer):return not layers[layer].get_cell_tile_data(coords_arr[i]))
			elif sequence[i].flag == NeighbourData.NeighbourFlag.Have:
				temp_is_match = sequence[i].layers.any(func (layer):return layers[layer].get_cell_tile_data(coords_arr[i]))
			if not temp_is_match:
				break
		if temp_is_match:
			is_match_rule = true
			break
	return is_match_rule
